package commands

import (
	"context"
	"fmt"
	"os"

	"github.com/containerd/containerd"
	"github.com/containerd/containerd/cio"
	"github.com/containerd/containerd/namespaces"

	cli "github.com/urfave/cli/v3"
)

var startCommand = &cli.Command{
	Name:      "start",
	Usage:     "Start a container",
	UsageText: "ruc start [options] CONTAINER",

	Flags: []cli.Flag{
		&cli.BoolFlag{
			Name:    "detach",
			Aliases: []string{"d"},
			Usage:   "Detach from the container after it has started execution",
		},
	},

	Action: start,

	ErrWriter:       os.Stderr,
	CommandNotFound: commandNotFoundHandler,
	ExitErrHandler:  exitErrHandler,
}

func start(ctx context.Context, cmd *cli.Command) error {
	if cmd.NArg() < 1 {
		return ErrNoImageProvided
	}

	client, err := containerd.New(
		containerdAddress,
		containerd.WithDefaultNamespace(namespaces.Default),
	)
	if err != nil {
		return err
	}
	defer client.Close()

	containerID := cmd.Args().First()

	container, err := client.LoadContainer(ctx, containerID)
	if err != nil {
		fmt.Fprintf(cmd.ErrWriter, "%q: %s\n", cmd.FullName(), err)
		return err
	}

	task, err := container.NewTask(ctx, cio.NewCreator(cio.WithStdio))
	if err != nil {
		fmt.Fprintf(cmd.ErrWriter, "%q: %s\n", cmd.FullName(), err)
		return err
	}

	exitStatusC, err := task.Wait(ctx)
	if err != nil {
		fmt.Fprintf(cmd.ErrWriter, "%q: %s\n", cmd.FullName(), err)
		return err
	}

	if err := task.Start(ctx); err != nil {
		fmt.Fprintf(cmd.ErrWriter, "%q: %s\n", cmd.FullName(), err)
		return err
	}

	// 脱离控制终端，后台运行
	if cmd.Bool("detach") {
		return nil
	}

	// 等待。
	// 子进程结束的 SIGCLID 或者是 stop 子命令发送的 SIGTERM，亦或是其他信号
	status := <-exitStatusC
	_, _, err = status.Result()
	if err != nil {
		fmt.Fprintf(cmd.ErrWriter, "%q: %s\n", cmd.FullName(), err)
		return err
	}

	return nil
}
